-----------------------------------------------------------------------------
--  DailyNotes is an Addon for Runes of Magic
--  It will show you additional information in tooltips and on bulleting boards.
--
--  (c) 2009 McBen (viertelvor12@gmx.net)
--
--  License: MIT/X
-----------------------------------------------------------------------------

DailyNotes = {

  -- runtime vars:
  Quest_count = 0, -- total count of quests in DB
  DB_Item = nil,   -- item names
}


DN_addon = {
  name          = "DailyNotes",
  version       = "1.7.3",
  description   = "Detailed information for daily-quest items.",
  author        = "McBen, rv55",
  icon          = "interface/AddOns/dailynotes/icon.dds",
  category      = "Inventory",
  slashCommand  = "/dn",
}

DN_F_TITLE = DN_addon.name.."  |cffa0a000v"..DN_addon.version


 -- the SAVE var
DN_Options={ 
  version = DN_addon.version, 

   -- DEFAULT OPTIONS:
  showcharlevel = true,  -- Show required level instead of quest level
  takefilter = true,     -- Only auto-take quest if items are in inventory
  verbose = false,       -- no additional infos
  noitemcount = false,   -- show item count in loot
   dqionly = true,       -- ^ but only for DQ items
}


-----------------------------------------------------------------------
-- Helpers
-----------------------------------------------------------------------
function DailyNotes:LoadFile(filename)
  local func, err = loadfile(filename)
  if (err) then
    DEFAULT_CHAT_FRAME:AddMessage("|cffff0000Error loading: "..filename.." ->"..tostring(err))
    return err
  end
  func()
end


function DailyNotes:LoadDB(loc)

  if loc ~= "de" then loc="en" end

  self:LoadFile("Interface/Addons/dailynotes/Locales/"..loc..".lua")
  self:LoadFile("Interface/Addons/dailynotes/quest_db.lua")

  -- count quest
  self.Quest_count = 0
  for _,_ in pairs(self.DB_Quests) do
     self.Quest_count = self.Quest_count+1
  end
end


-- LOAD DB
DailyNotes:LoadDB(string.sub(GetLanguage():lower(),1,2))





--[===[@debug@
--------------------------------------------------------
-- Runtime check
-----------------------------------------------------------------------
function DailyNotes:TestDB()

  local error_messages=nil
  local function ErrorOut(text,qid)
    error_messages = error_messages or {}
    table.insert(error_messages,text .. " quest="..tostring(qid).."/"..tostring(DailyNotes.DB_QID[qid]))
  end

  for qid,quest in pairs(self.DB_Quests) do

     -- quest name
     if not DailyNotes.DB_QID[qid] then
        ErrorOut("quest not in locales: ",qid)
     end

     -- quest level
     if quest.rlvl>quest.lvl then
        ErrorOut("quest req.level greater then level: ",qid)
     end

     if quest.lvl<1 or quest.lvl>52 or quest.rlvl<1 or quest.rlvl>50 then
        ErrorOut("illegal level "..tostring(quest.lvl).."/"..tostring(quest.rlvl),qid)
     end

     if not GetZoneLocalName(quest.zone) then
        ErrorOut("unknown zoneid="..tostring(quest.zone),qid)
     end
     if not self.DB_Zones[quest.zone] then
        ErrorOut("not in DB_Zones zoneid="..tostring(quest.zone),qid)
     end

     for itemid,_ in ipairs(quest.items or {}) do
        if not self.DB_Item[itemid] then
          ErrorOut("item no defined: '"..itemid.."'",qid)
        end
     end

     for _,giv in ipairs(quest.giver) do
        if not self.DB_NPC[giv] then
          ErrorOut("start npc not defined: '"..giv.."'",qid)
        end
     end
 end


 if error_messages then

   DEFAULT_CHAT_FRAME:AddMessage("|cffff0000---------------------------------------")
   DEFAULT_CHAT_FRAME:AddMessage("|cffff0000DailyNotes: problems to solve:")

   for _,t in ipairs(error_messages) do
    DEFAULT_CHAT_FRAME:AddMessage("|cffff8080"..t)
   end

   DEFAULT_CHAT_FRAME:AddMessage("|cffff0000---------------------------------------")
 end

end

--------------------------------------------------------
--@end-debug@]===]


-----------------------
function DailyNotes.DN_GetItemID( itemLk )

  if itemLk==nil then return end

  local ret = "";
  local _type, _data, _name = ParseHyperlink(itemLk);

  if ( _data and _data ~= "" ) then
    _,_,ret = string.find(_data, "(%x+)")
    ret = ret:lower()
  end

  return ret;
end


-----------------------
function DailyNotes.CreateItemLink( item_id,quality )
  local r,g,b = GetItemQualityColor(quality or 1)

  return '|Hitem:' ..tostring(item_id).. '|h|cff'..string.format("%2x%2x%2x",r*255,g*255,b*255)..'['..(DailyNotes.DB_Item[item_id] or 'unknown')..']|r|h';
end

-----------------------
function DailyNotes.DN_GetCurrentChar()
  local realm=string.match((GetCurrentRealm() or ""),"(%w*)$")
  realm = realm or (GetCurrentRealm() or "")
  return realm..':'..( UnitName("player") or "")
end


-----------------------
function DailyNotes:GetTotalItemCount(itemID)
  local total = 0
  for i = 51, 240 do 
    local icon, _, itemCount, _ = GetGoodsItemInfo( i )
    if ( icon~="" ) then
      if ( self.DN_GetItemID(GetBagItemLink( i ))==itemID ) then
        total=total+itemCount
      end
    end
  end
  return total
end

------------------------------
function DailyNotes:FindQuestForItem(itemID)
  for qid,e in pairs(self.DB_Quests) do
    if e.items and e.items[itemID] then
      return qid,e
    end
  end
end

------------------------------
function DailyNotes:FindQuestByName(qname)
  for qid,e in pairs(self.DB_Quests) do
    if self.DB_QID[qid]==qname then
      return qid,e
    end
  end
end

------------------------------
function DailyNotes:GetQuestItems(qudata)

  if not qudata then return end
  if not qudata.items then return 0,{},0 end


  local itemcounts = {}
  local max_completed=nil
  local finish_able
  local total=0
  for iid,count in pairs(qudata.items) do
    itemcounts[iid] = self:GetTotalItemCount(iid)
    finish_able = math.floor(itemcounts[iid]/count)
    total = total + itemcounts[iid]
    if not max_completed or finish_able<max_completed then
      max_completed = finish_able
    end
  end

  return max_completed,itemcounts,total
end

------------------------------
-- return: Name,map,pos_x,pos_y,sub_zone
function DailyNotes:GetNPCInfo(npc_id)

  -- cached
  local n_name,n_map,n_posx,n_posy,n_subzone

  if self.DB_NPC[npc_id] then
    n_name = self.DB_NPC[npc_id].name
    n_map  = self.DB_NPC[npc_id].map
    n_posx = self.DB_NPC[npc_id].x
    n_posy = self.DB_NPC[npc_id].y
    n_subzone = self.DB_NPC[npc_id].subzone

    if n_name then
      return n_name,n_map,n_posx,n_posy,n_subzone
    end
  else
    n_name = npc_id
    n_map  = 10000
    n_posx = 50
    n_posy = 50
    n_subzone = "unknown"
  end


  if npc_id and type(npc_id)=="number" and ( NpcTrack_SearchNpcByDBID( npc_id ) >0 )then
    _, n_name, n_map, n_posx, n_posy = NpcTrack_GetNpc(1)
    n_posx = math.floor(n_posx*1000)/10
    n_posy = math.floor(n_posy*1000)/10

    self.DB_NPC[npc_id] = {map=n_map,name=n_name,subzone=n_subzone,x=n_posx,y=n_posy}
  end

  return n_name,n_map,n_posx,n_posy,n_subzone

end


------------------------------
function DailyNotes:MakeItemCountString(qudata,icounts)

  local pre=nil
  local post=nil

  for iid,count in pairs(qudata.items or {}) do
    if pre then
      pre = pre..",".. (icounts[iid] or 0)
      post = post..","..count
    else
      pre = (icounts[iid] or 0)
      post = count
    end
  end

  for iid,count in pairs(qudata.mobs or {}) do
    if pre then
      pre = pre..",".. (icounts[iid] or 0)
      post = post..","..count
    else
      pre = (icounts[iid] or 0)
      post = count
    end
  end

  if not pre then return "??" end
  return pre.."/"..post,pre,post
end


------------------------------
-- many thanks to pbinfo
function DailyNotes.CHAT_MSG_SYSTEM(msg)

  local offset = 0;
  if (tonumber(os.date("!%H")) < 5) then -- dailies are reset at 5am UTC each day
      offset = 1;
  end;

  local dailies = (
    string.match(msg, DN_F_DAILY_QUEST_PATTERN[1])
    or (string.find(msg, DN_F_DAILY_QUEST_PATTERN[2]) and "0")
    or (string.find(msg, DN_F_DAILY_QUEST_PATTERN[3]) and "10")
  );

  if (type(dailies) == "string") then
      dailies = tonumber(dailies);

      if (dailies >= 0) then
        DN_Options[DailyNotes.DN_GetCurrentChar()]["DAILIES"] = {dailies, os.time()}
      end
  end
end


------------------------------
local function DN_GetDailiesCount()

  local charid = DailyNotes.DN_GetCurrentChar()
  if not DN_Options[charid] or not DN_Options[charid]["DAILIES"] then
    DN_Options[charid] = {}
    DN_Options[charid]["DAILIES"]={10,0}
  end

  local dailies = DN_Options[charid]["DAILIES"][1]
  local time  = DN_Options[charid]["DAILIES"][2]

  -- Test reset
  local offset = 0
    if (tonumber(os.date("!%H")) < 5) then -- dalies are reset at 5am UTC each day
      offset = 1
    end;

  local lastreset = os.time({day = os.date("!%d")-offset, month = os.date("!%m"), year = os.date("!%Y"), hour = 5, min = 0, sec = 0});
  if (os.difftime(lastreset, DN_Options[charid]["DAILIES"][2]) >= 0) then
      DN_Options[charid]["DAILIES"] = {10, os.time()};
      dailies=10;
    end

  return dailies
end

------------------------------
function DailyNotes.CHAT_MSG_SYSTEM_GET()

  if ( DN_Options.disabled or DN_Options.noitemcount ) then  return;  end
  
  local itemid = DailyNotes.DN_GetItemID( string.gsub(arg1,"^.*\|H","|H")) 
  
  -- check if DQ item
  local _,quest = DailyNotes:FindQuestForItem(itemid)
  local target = quest and quest.items and quest.items[itemid]

  if target then  
    local count = DailyNotes:GetTotalItemCount(itemid)  
  	arg1 = arg1 .." |cffffff00("..count .."/"..target..")"
  else
    if not DN_Options.dqionly then
      local count = DailyNotes:GetTotalItemCount(itemid)  
      if count>1 then
  	    arg1 = arg1 .." |cffffff00("..count..")"
      end
    end
  end
end

------------------------------
-- Return player main and secondary level
-- (secondary not depending on current main-class)
local function DN_GetPlayerLevel()

  mainClass, secondClass = UnitClass( "player" )

  local mlvl=0
  local slvl=0

  local numClasses = GetNumClasses()
  for i = 1, numClasses do
    local class, token, level, currExp, maxExp = GetPlayerClassInfo(i)
    if mainClass and   mainClass==class then mlvl = level end
    if secondClass and secondClass==class then slvl = level end
  end

  return mlvl,slvl
end


-----------------------------------------------------------------------
-- Tooltips
-- many thanks to Inventory Viewer :)
-----------------------------------------------------------------------
local orig_GameTooltipHyperLinkSetHyperLink = GameTooltipHyperLink["SetHyperLink"];
local orig_GameTooltipSetHyperLink = GameTooltip["SetHyperLink"];
local orig_GameTooltipSetBagItem = GameTooltip["SetBagItem"];
local orig_GameTooltipSetBankItem = GameTooltip["SetBankItem"];
local orig_GameTooltipSetAuctionBrowseItem = GameTooltip["SetAuctionBrowseItem"];
local orig_GameTooltipSetBootyItem = GameTooltip["SetBootyItem"];
local orig_GameTooltipSetActionItem=GameTooltip["SetActionItem"];



function DailyNotes:AppendTooltipData(tooltip, itemLink )

  if ( DN_Options["disabled"] or not itemLink or itemLink == "" ) then
    return;
  end

  local itemid = DailyNotes.DN_GetItemID(itemLink)
  local qid,quest = self:FindQuestForItem(itemid)

  if qid then

    -- Count and Name
    local max_completed, itemcounts = self:GetQuestItems(quest)

    tooltip:AddLine( string.format(DN_T_COUNT, itemcounts[itemid], quest.items[itemid], self:GetNPCInfo(quest.taker))) -- "8/10 for questname"

    if (max_completed>0) then

      tooltip:AddLine( string.format(DN_T_FIN, max_completed)) -- "Enough for: %i times"
    else
      local needs = quest.items[itemid]-itemcounts[itemid]
      if needs<0 then
        tooltip:AddLine( string.format(DN_T_NEEDSOTHER)) -- "Needs other item"
      else
        tooltip:AddLine( string.format(DN_T_NEED, needs)) -- "Needs: %i"
      end
    end

    -- Name and Level
    local col = ""
    local mlvl, slvl = DN_GetPlayerLevel()
    if (quest.lvl > mlvl) then
      col = "|cffff0000"
      if (quest.lvl <= slvl) then
        col = "|cffff8080"
      end
    end
    tooltip:AddLine( col .. DailyNotes.DB_QID[qid] .. " (Lvl " .. quest.lvl .. ")");


    -- Where to get it
    local last_start = nil
    for key,value in pairs(quest.giver) do
      local n_name,n_map,n_posx,n_posy,n_subzone = DailyNotes:GetNPCInfo(value)

      if n_name ~= last_start then
        tooltip:AddLine( string.format(DN_T_QSTART, n_name)) -- Start: %s
        if DN_Options.verbose then
          tooltip:AddLine( string.format(DN_T_QSPOS, GetZoneLocalName(n_map),n_posx,n_posy)) -- (%s: %g/%g)
        end
        last_start = n_name
      end
    end

    -- reward npc
    if DN_Options.verbose and quest.taker then
      local n_name,n_map,n_posx,n_posy,n_subzone = DailyNotes:GetNPCInfo(quest.taker)

      tooltip:AddLine( string.format(DN_T_QEND, n_name)) -- Start: %s
      if DN_Options.verbose then
        tooltip:AddLine( string.format(DN_T_QSPOS, GetZoneLocalName(n_map),n_posx,n_posy)) -- (%s: %g/%g)
      end
    end


    -- XP/Gold/Token (Note: TPs=floor(XP/10))
    tooltip:AddLine( string.format(DN_T_XP, quest.rew[1],quest.rew[2],quest.rew[3])) -- XP: %i   Gold/Token: %i/%i

    if DN_Options.debug and quest.typ<0 then
      tooltip:AddLine( "|cffff0000(--UNTESTED-- Plz report)")
    end

  else

    if DN_Options.debug then
      tooltip:AddLine( "\n|cff909090ItemID: " .. DailyNotes.DN_GetItemID(itemLink));
    end
  end
end


function GameTooltip:SetBankItem( BankId )
  orig_GameTooltipSetBankItem( self, BankId )
  DailyNotes:AppendTooltipData( self, GetBankItemLink( BankId ) )
end

function GameTooltip:SetBagItem( BankId )
  orig_GameTooltipSetBagItem( self, BankId )
  DailyNotes:AppendTooltipData( self, GetBagItemLink( BankId ) )
end

function GameTooltip:SetHyperLink( itemLink )
  orig_GameTooltipSetHyperLink( self, itemLink )
  DailyNotes:AppendTooltipData( self, itemLink )
end

function GameTooltipHyperLink:SetHyperLink( itemLink )
  orig_GameTooltipHyperLinkSetHyperLink( self, itemLink )
  DailyNotes:AppendTooltipData( self, itemLink )
end

function GameTooltip:SetAuctionBrowseItem(id)
  orig_GameTooltipSetAuctionBrowseItem(self, id)
  DailyNotes:AppendTooltipData( self, GetAuctionBrowseItemLink(id) )
end

function GameTooltip:SetBootyItem(id)
  orig_GameTooltipSetBootyItem(self, id)
  DailyNotes:AppendTooltipData( self, GetBootyItemLink(id) )
end


function DailyNotes:DN_FindBagIndex(m_name,m_icon)
    local inventoryIndex, icon, name;
    local _,bagcount=GetBagCount();
    for i=1,bagcount do
        inventoryIndex, icon, name= GetBagItemInfo ( i );
        if name==m_name and icon==m_icon then
            return inventoryIndex;
        end;
    end
    return nil;
end

function GameTooltip:SetActionItem(m_ButtonId)
    local result=orig_GameTooltipSetActionItem (self,m_ButtonId)
    local icon_path = GetActionInfo(m_ButtonId)
    if icon_path then
      local itemname = _G[GameTooltip:GetName() .. "TextLeft1"]:GetText()
      if itemname then
        local iidx=DailyNotes:DN_FindBagIndex(itemname,icon_path)
        if iidx then
            DailyNotes:AppendTooltipData( self, GetBagItemLink( iidx ) )
        end
      end
    end
    return result;
end


function DailyNotes.UPDATE_MOUSEOVER_UNIT()
  DailyNotes_mobtools = nil
  if (not UnitCanAttack("player", "mouseover") or UnitIsPlayer("mouseover")) then
    return
  end
  local guid = UnitName("mouseover");
  DailyNotes_mobtools = "name=" .. tostring(guid)
  GameTooltip:AddLine(DailyNotes_mobtools);
end



-----------------------------------------------------------------------
--  Bulletin Board / Quest givers
-----------------------------------------------------------------------
local orig_SpeakFrame_LoadQuest = SpeakFrame_LoadQuest
local orig_SpeakFrame_LoadQuestDetail = SpeakFrame_LoadQuestDetail

local function DN_ChangeSpeakFrame(detail)

  if ( DN_Options["disabled"] ) then  return;  end

  local finishable_quest = nil
  local finishable_quest_type = DF_IconType_NewQuest
  local new_quest_id = 0
  local comp_quest_id = 0

  local to_sort={}

  for i= 1,g_SpeakFrameData.count do
   -- NEW Quests
    if g_SpeakFrameData.option[i].type==DF_IconType_NewQuest then
      new_quest_id=new_quest_id+1
      local name = g_SpeakFrameData.option[i].title
      if detail and name:find("^"..SPEAKFRAME_QUEST_ACCEPT)  then name = name:sub(SPEAKFRAME_QUEST_ACCEPT:len()+1) end


      local qid,qdata = DailyNotes:FindQuestByName(name)
      if qid then

        local count, itemcounts = DailyNotes:GetQuestItems(qdata)
        kind = (math.abs(qdata.typ)%16)

        table.insert(to_sort,{i,qdata.rew[1],DF_IconType_NewQuest}) -- store for sort

        local col = ""
        if count>0 then
          g_SpeakFrameData.option[i].type = DF_IconType_RepeatQuestDone
          col="|cff40ff40"
        else
          g_SpeakFrameData.option[i].type = DF_IconType_RepeatQuest
          if kind==2 then col = "|cffb0b0ff" end -- kill quest
        end
        g_SpeakFrameData.option[i].title = col.."["..qdata.lvl.."] "..g_SpeakFrameData.option[i].title.." ("..DailyNotes:MakeItemCountString(qdata,itemcounts)..")"

        -- check auto quest
        if DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest and
              ( (count>0 or kind==2 or kind==4) or -- finishable, kill or gather quest
                (not DN_Options.takefilter) ) then
          if DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept and DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] then
            finishable_quest = new_quest_id
            finishable_quest_type = 1
          end
        end

        -- we changed the type .. so we need to handle the click
        if not detail then
          g_SpeakFrameData.option[i].script = function (type, id ) OnClick_QuestListButton(1,id) end
        end

        if qdata.typ<0 and DN_Options.debug then
          g_SpeakFrameData.option[i].type = DF_IconType_Flag
          g_SpeakFrameData.option[i].title= "|cffffffff"..g_SpeakFrameData.option[i].title
        end
      end

    -- Finished Quest
    elseif g_SpeakFrameData.option[i].type==DF_IconType_FinishedQuest then
      comp_quest_id=comp_quest_id+1
      local name = g_SpeakFrameData.option[i].title
      if detail and name:find("^"..SPEAKFRAME_QUEST_COMPLETE) then
        name = name:sub(SPEAKFRAME_QUEST_COMPLETE:len()+1)
      end

      local qid,qdata = DailyNotes:FindQuestByName(name)
      if qid then

        local count, itemcounts = DailyNotes:GetQuestItems(qdata)

        table.insert(to_sort,{i,qdata.rew[1],DF_IconType_FinishedQuest}) -- store for sort

        g_SpeakFrameData.option[i].type = DF_IconType_RepeatQuestDone
        g_SpeakFrameData.option[i].title= "|cff40ff40"..g_SpeakFrameData.option[i].title

        kind = (math.abs(qdata.typ)%16)
        if kind ~= 2 and count>0 then
          g_SpeakFrameData.option[i].title= g_SpeakFrameData.option[i].title.." ("..DailyNotes:MakeItemCountString(qdata,itemcounts)..")"
        end

        -- check auto quest
        if DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest then -- autofinish?
          if DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept and DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] then
            finishable_quest = comp_quest_id
            finishable_quest_type = DF_IconType_FinishedQuest
          end
        end

        -- we changed the type .. so we need to handle the click
        if not detail then
          g_SpeakFrameData.option[i].script = function (type, id ) OnClick_QuestListButton(3,id) end
        end
      end
    end
  end

  local positions={}
  for _,p in pairs(to_sort) do table.insert(positions,p[1]) end
  table.sort(to_sort,function(a,b) return a[2]>b[2] end)
  temp = g_SpeakFrameData.option
  for n,p in pairs(positions) do
--    g_SpeakFrameData.option[p] = temp[n]
--    DEFAULT_CHAT_FRAME:AddMessage("DN: "..p.."=".. n)
  end

  -- 'repaint'
  SpeakFrame_Show()


  -- catch: 10 dailies already done
  if finishable_quest_type==DF_IconType_FinishedQuest and DN_GetDailiesCount() <= 0 then
    finishable_quest = nil
  end

  if finishable_quest then
    -- in detail view: accept/complete
    if detail==1 then
      if finishable_quest_type==1 then
         AcceptQuest()
      else
         CompleteQuest()
      end
      SpeakFrame_Hide()
    else
      -- request detail view
      OnClick_QuestListButton(finishable_quest_type,finishable_quest)
    end
  end
end


function SpeakFrame_LoadQuest()
  orig_SpeakFrame_LoadQuest()
  DN_ChangeSpeakFrame()
end

function SpeakFrame_LoadQuestDetail( Quitmode )
  orig_SpeakFrame_LoadQuestDetail( Quitmode )
  DN_ChangeSpeakFrame(1)
end


-----------------------------------------------------------------------
-- DN Frame
-----------------------------------------------------------------------
local DAILY_NOTES_MAX_ENTRIES = 15;

local DN_filter_list=nil

-- TODO: add item and target sort
local DN_fct_compare={
 -- count
 function (a,b)  return a[4]>b[4] end,
 -- target
 function (a,b)  return false end,
 -- name
 function (a,b)  return DailyNotes.DB_QID[a[1]]<DailyNotes.DB_QID[b[1]] end,
 -- level
 function (a,b)  if DN_Options.showcharlevel then return a[2].rlvl>b[2].rlvl end return a[2].lvl>b[2].lvl end,
 -- zone
 function (a,b)  return GetZoneLocalName(a[2].zone)<GetZoneLocalName(b[2].zone) end,
 -- item
 function (a,b)  return DailyNotes.GetQuestItemName(a[2])<DailyNotes.GetQuestItemName(b[2]) end,
 -- xp
 function (a,b)  return a[2].rew[1]>b[2].rew[1] end,
}

local DN_fct_filter_status={
  function(fin,count) return true end,
  function(fin,count) return fin>0 end,
  function(fin,count) return count>0 end
}

function DailyNotes.GetQuestItemName(qdata)
  local itemid = next(qdata.items or {})
  if itemid then return DailyNotes.DB_Item[itemid] end
  local mobid = next(qdata.mobs or {})
  if mobid then return DailyNotes:GetNPCInfo(mobid) end
  return ""
end


---------------------------------
function DailyNotes:UpdateList()

  -- Get Options
  local status_filter = DN_fct_filter_status[UIDropDownMenu_GetSelectedID(DNFFilterCountDropDown)] or DN_fct_filter_status[1]

  local nzone_filter = DN_Options[DailyNotes.DN_GetCurrentChar()].FilterZone
  if nzone_filter == -1 then
     nzone_filter = GetCurrentWorldMapID()
  elseif nzone_filter == 0 then
     nzone_filter = nil
  end

  DN_Options[DailyNotes.DN_GetCurrentChar()].FilterStatus = UIDropDownMenu_GetSelectedID(DNFFilterCountDropDown)


  -- Get filtered list
  local mlvl, slvl = DN_GetPlayerLevel()

  self.view_items={}
  for qid,qdata in pairs(self.DB_Quests) do
    local finished,itemcounts,count = self:GetQuestItems(qdata)
    if not nzone_filter or (qdata.zone==nzone_filter or self.DB_Zones[nzone_filter]==qdata.zone or self.DB_Zones[qdata.zone]==nzone_filter) then -- zone filter
      -- status filter (finished, started, none)
      if status_filter(finished,count) then     
         -- main class level filter (can take quest)
        if (DN_Options.filtermain and mlvl>=qdata.rlvl) or 
           -- second class level filter (can take quest or main can take and second can reward it)
           (DN_Options.filtersec  and (slvl>=qdata.lvl or (slvl>=qdata.lvl-10 and mlvl>=qdata.rlvl))) or 
           -- (or no level filter)
           (not DN_Options.filtermain and not DN_Options.filtersec)  then
          table.insert(self.view_items,{qid,qdata,finished,count,itemcounts})
        end
      end
    end
  end

  -- Sort
  if DN_Options.Sort and DN_Options.Sort<0 then
    table.sort(self.view_items, function (a,b) return DN_fct_compare[-DN_Options.Sort](b,a) end)
  else
    table.sort(self.view_items, DN_fct_compare[DN_Options.Sort] or DN_fct_compare[1])
  end


  -- Update view
  if #self.view_items > DAILY_NOTES_MAX_ENTRIES then
    DailyNotesListScrollBar:Show();
    DailyNotesListScrollBar:SetMinMaxValues(0, #self.view_items-DAILY_NOTES_MAX_ENTRIES);
  else
    DailyNotesListScrollBar:Hide();
    DailyNotesListScrollBar:SetMinMaxValues(0, 0);
  end

  DailyNotesListSize:SetText(#self.view_items.." / ".. DailyNotes.Quest_count)

  DailyNotes:UpdateListView()
end



function DN_List_Header_OnClick(this)

  local id = this:GetID()
  DailyNotesListCountHeaderSortIcon:SetFile("");
  DailyNotesListTargetHeaderSortIcon:SetFile("");
  DailyNotesListLevelHeaderSortIcon:SetFile("");
  DailyNotesListNameHeaderSortIcon:SetFile("");
  DailyNotesListZoneHeaderSortIcon:SetFile("");
  DailyNotesListItemHeaderSortIcon:SetFile("");
  DailyNotesListXPHeaderSortIcon:SetFile("");

  if(DN_Options.Sort == id or DN_Options.Sort == -id ) then
    DN_Options.Sort = -DN_Options.Sort
  else
    DN_Options.Sort = id;
  end

  if DN_Options.Sort>0 then
    getglobal(this:GetName() .. "SortIcon"):SetFile("Interface/chatframe/chatframe-scrollbar-buttondown")
  else
    getglobal(this:GetName() .. "SortIcon"):SetFile("Interface/chatframe/chatframe-scrollbar-buttonup")
  end

  DailyNotes:UpdateList()
end

----------------------------
function DailyNotes:OnShow()
  UIDropDownMenu_SetSelectedID(DNFFilterCountDropDown, DN_Options[DailyNotes.DN_GetCurrentChar()].FilterStatus or 1);
  DNFFilterCountDropDownText:SetText(DN_F_C_COUNT[DN_Options[DailyNotes.DN_GetCurrentChar()].FilterStatus or 1])

  -- set zone
  local zone_text=""
  local z = DN_Options[DailyNotes.DN_GetCurrentChar()].FilterZone or 0
  if z==0 then zone_text=DN_F_C_ZONE_ALL
  elseif z==-1 then zone_text=DN_F_C_ZONE_CUR
  else
    if z == 670 then
      zone_text = DN_ZONE_YLAB
    else
     zone_text=GetZoneLocalName(z)
    end
  end
  UIDropDownMenu_SetSelectedName(DNFFilterZoneDropDown, zone_text)
  DNFFilterZoneDropDownText:SetText(zone_text)

  DailyNotesFilterLevel1:SetChecked(DN_Options.filtermain)
  DailyNotesFilterLevel2:SetChecked(DN_Options.filtersec)
  DailyNotesAutoQuest:SetChecked(DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest)

  self.UpdateAQButtons()
  self:UpdateList()
end

------------------------
function DailyNotes:OnHide()
  self.view_items=nil
end

----------------------------
-- TODO: finish
function DailyNotes:UpdateListView()

  local index = DailyNotesListScrollBar:GetValue()
  local entry,key,button

  local mlvl, slvl = DN_GetPlayerLevel()

  local button,qid,qdata,qname

  for i = 1, DAILY_NOTES_MAX_ENTRIES do
    button = getglobal("DailyNotesListItem"..i);


    if self.view_items[index+i] then
      qid = self.view_items[index+i][1]
      qdata = self.view_items[index+i][2]
      qname = self.DB_QID[qid]

      buttonName = button:GetName();

      local _,count, target = self:MakeItemCountString(qdata,self.view_items[index+i][5])
      getglobal(buttonName.."Counter"):SetText(count)
      getglobal(buttonName.."Target"):SetText(target)

      if DN_Options.showcharlevel then
        getglobal(buttonName.."Level"):SetText(qdata.rlvl)
      else
        getglobal(buttonName.."Level"):SetText(qdata.lvl)
      end

      getglobal(buttonName.."Name"):SetText(qname);
      getglobal(buttonName.."Zone"):SetText(GetZoneLocalName(qdata.zone));
      getglobal(buttonName.."Item"):SetText(DailyNotes.GetQuestItemName(qdata));
      getglobal(buttonName.."XP"):SetText(qdata.rew[1])

      r,g,b=1,1,1
      if self.view_items[index+i][3]>0 then r,g,b=0,1,0 -- FINISHED
      elseif (math.abs(qdata.typ)%16)==2  then r,g,b=0.7,0.7,1 -- Kill Quest
      elseif DN_Options.debug and qdata.typ<0 then r,g,b=1,0,0    -- NEED TEST
      end

      getglobal(buttonName.."Counter"):SetColor(r,g,b)
      getglobal(buttonName.."Target"):SetColor(r,g,b)
      getglobal(buttonName.."Level"):SetColor(r,g,b)
      getglobal(buttonName.."Name"):SetColor(r,g,b)
      getglobal(buttonName.."Zone"):SetColor(r,g,b)
      getglobal(buttonName.."Item"):SetColor(r,g,b)
      getglobal(buttonName.."XP"):SetColor(r,g,b)

      if DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest then
        getglobal(buttonName.."Check"):Show()
        getglobal(buttonName.."Check"):SetChecked(DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept and DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid])
      else
        getglobal(buttonName.."Check"):Hide()
      end

      button:Show();
    else
      button:Hide();
    end
  end

  DN_List_UpdateDoAble()
end


------------
-- List tooltip
function DN_List_Item_OnEnter(this)

  local highlightText = getglobal(this:GetName().."Highlight");
  highlightText:SetColor(1, 1, 0);
  highlightText:Show()

  GameTooltip:ClearAllAnchors();
  GameTooltip:SetAnchor("TOPLEFT", "BOTTOMRIGHT", this:GetName(),2,0);

  local index = DailyNotesListScrollBar:GetValue() + this:GetID()
  if not DailyNotes.view_items[index] then return end
  local qid = DailyNotes.view_items[index][1]
  local qdata = DailyNotes.view_items[index][2]

  local old_verb_val = DN_Options.verbose
  DN_Options.verbose = true

  -- Show the tooltip
  GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT", 0, 0);
  local ty=(math.abs(qdata.typ)%16)

  if qdata.items then

    -- normal: standard item tooltip
    local itemid,_ = next(qdata.items)
    GameTooltip:SetHyperLink( DailyNotes.CreateItemLink( itemid) );
    GameTooltip:Show();

  elseif qdata.mobs then

    -- kill quest need manual tooltip
    GameTooltip:SetText("")
    local first=true
    for mobid,mobcount in pairs(qdata.mobs or {}) do
      if first then
        GameTooltip:SetText(DailyNotes:GetNPCInfo(mobid))
        GameTooltip:AddLine("")
        first = nil
      else
        GameTooltip:AddLine("+ " .. DailyNotes:GetNPCInfo(mobid))
      end
      GameTooltip:AddLine(string.format(DN_T_KILLCOUNT, mobcount, DailyNotes:GetNPCInfo(qdata.taker))) -- "10 for taker"
    end

    -- Name and Level
    local col = ""
    local mlvl, slvl = DN_GetPlayerLevel()
    if (qdata.lvl > mlvl) then
      col = "|cffff0000"
      if (qdata.lvl <= slvl) then
        col = "|cffff8080"
      end
    end
    GameTooltip:AddLine(col..DailyNotes.DB_QID[qid] .. " (Lvl " .. qdata.lvl .. ")")

    -- Where to get it
    local last_start = nil
    for key,value in pairs(qdata.giver) do
      local n_name,n_map,n_posx,n_posy,n_subzone = DailyNotes:GetNPCInfo(value)

      if n_name ~= last_start then
        GameTooltip:AddLine( string.format(DN_T_QSTART, n_name)) -- Start: %s
        if DN_Options.verbose then
          GameTooltip:AddLine( string.format(DN_T_QSPOS, GetZoneLocalName(n_map),n_posx,n_posy)) -- (%s: %g/%g)
        end
        last_start = n_name
      end
    end

   -- reward npc
    if DN_Options.verbose and qdata.taker then
      local n_name,n_map,n_posx,n_posy,n_subzone = DailyNotes:GetNPCInfo(qdata.taker)

      GameTooltip:AddLine( string.format(DN_T_QEND, n_name)) -- Start: %s
      if DN_Options.verbose then
        GameTooltip:AddLine( string.format(DN_T_QSPOS, GetZoneLocalName(n_map),n_posx,n_posy)) -- (%s: %g/%g)
      end
    end

    -- XP/Gold/Token (Note: TPs=floor(XP/10))
    GameTooltip:AddLine( string.format(DN_T_XP, qdata.rew[1],qdata.rew[2],qdata.rew[3])) -- XP: %i   Gold/Token: %i/%i
    GameTooltip:Show();

  else
      DEFAULT_CHAT_FRAME:AddMessage("|cffff0000DN: no mob and no item defined")
  end

  DN_Options.verbose = old_verb_val
end


function DN_List_Item_OnLeave(this)
  local highlightText = getglobal(this:GetName().."Highlight");
  highlightText:SetColor(1, 1, 1);
  highlightText:Hide();
  GameTooltip:Hide();
end

------------
-- Count filter
function DN_FCountDropDown_OnLoad(this)
  UIDropDownMenu_SetWidth(this, 80)
  UIDropDownMenu_Initialize(this, DN_FCountDropDown_Show)
  UIDropDownMenu_SetSelectedID(DNFFilterCountDropDown, 0)
end

function DN_FCountDropDown_Show()
  local info;
  info = {};
  info.text = DN_F_C_COUNT[1]
  info.func = DN_FilterCountDropDown_Click;
  UIDropDownMenu_AddButton(info);

  info = {};
  info.text = DN_F_C_COUNT[2]
  info.func = DN_FilterCountDropDown_Click;
  UIDropDownMenu_AddButton(info);

  info = {};
  info.text = DN_F_C_COUNT[3]
  info.func = DN_FilterCountDropDown_Click;
  UIDropDownMenu_AddButton(info);
end


function DN_FilterCountDropDown_Click(button)
  UIDropDownMenu_SetSelectedID(DNFFilterCountDropDown, button:GetID())
  DailyNotes:UpdateList()
end


------------
-- zone filter
function DN_FZoneDropDown_OnLoad(this)
  UIDropDownMenu_SetWidth(this, 100)
  UIDropDownMenu_Initialize(this, DN_FZoneDropDown_Show)
  UIDropDownMenu_SetSelectedID(DNFFilterZoneDropDown, 1)
end

function DN_FZoneDropDown_Show()
  local info;

  info = {};
  info.func = DN_FilterZoneDropDown_Click;
  info.text = DN_F_C_ZONE_ALL
  info.value = 0
  UIDropDownMenu_AddButton(info);

  info = {};
  info.func = DN_FilterZoneDropDown_Click;
  info.text = DN_F_C_ZONE_CUR
  info.value = -1
  UIDropDownMenu_AddButton(info);

  local zones={}
  local zones_in={}
  for _,d in pairs(DailyNotes.DB_Quests) do
    if not zones_in[d.zone] then
      zones_in[d.zone]=1
      table.insert(zones,{d.zone,GetZoneLocalName(d.zone)})
    end
  end
  -- ystra-lab
  table.insert(zones,{670,DN_ZONE_YLAB})


  table.sort(zones,function (a,b) return a[2]<b[2] end)

  for _,n in ipairs(zones) do
    info = {};
    info.func = DN_FilterZoneDropDown_Click;
    info.text = n[2]
    info.value= n[1]
    UIDropDownMenu_AddButton(info);
  end
end


function DN_FilterZoneDropDown_Click(button)
  UIDropDownMenu_SetSelectedID(DNFFilterZoneDropDown, button:GetID())
  DN_Options[DailyNotes.DN_GetCurrentChar()].FilterZone = button.value
  DailyNotes:UpdateList()
end

------------
-- levels
function DN_FilterLevel(btn)
  DN_Options.filtermain = DailyNotesFilterLevel1:IsChecked()
  DN_Options.filtersec  = DailyNotesFilterLevel2:IsChecked()

  DailyNotes:UpdateList()
end


------------
-- AutoQuest
function DN_AutoQuest(btn)
  DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest = DailyNotesAutoQuest:IsChecked()
  DailyNotes.UpdateAQButtons()
  DailyNotes:UpdateListView()
end


function DailyNotes.UpdateAQButtons()
  if DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest then
    DailyNoteAQClear:Show()
    DailyNoteAQAll:Show()
    DailyNoteAQKill:Show()
    DailyNoteAQGather:Show()
    DailyNoteAQKill:UnlockPushed()
    DailyNoteAQGather:UnlockPushed()

    -- check for 'all kill' and 'all gather'
    DailyNotes.AQ_AllKillMarked=1
    DailyNotes.AQ_AllGatherMarked=1
    if DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept then
      for qid,qdata in pairs(DailyNotes.DB_Quests) do
        if (math.abs(qdata.typ)%16)==2 then
          DailyNotes.AQ_AllKillMarked = DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] and DailyNotes.AQ_AllKillMarked
        elseif (math.abs(qdata.typ)%16)==4 then
          DailyNotes.AQ_AllGatherMarked = DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] and DailyNotes.AQ_AllGatherMarked
        end
      end
    else
      DailyNotes.AQ_AllKillMarked=nil
      DailyNotes.AQ_AllGatherMarked=nil
    end

    if DailyNotes.AQ_AllKillMarked   then DailyNoteAQKill:LockPushed() end
    if DailyNotes.AQ_AllGatherMarked then DailyNoteAQGather:LockPushed() end

  else
    DailyNoteAQClear:Hide()
    DailyNoteAQAll:Hide()
    DailyNoteAQKill:Hide()
    DailyNoteAQGather:Hide()
  end
end


function DN_AutoQuestSetCheck(btn,ischecked)
  local index = DailyNotesListScrollBar:GetValue() + btn:GetID()

  local qid = DailyNotes.view_items[index][1]
  if qid then
    if not DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept then DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept={} end
    if ischecked then
      DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] = 1
    else
      DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid] = nil
    end

    DailyNotes.UpdateAQButtons()
  end
end

function DN_AutoQuestClear()
   DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept={}
   DailyNotes.UpdateAQButtons()
   DailyNotes:UpdateListView()
end

function DN_AutoQuestSelectAll()
   DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept={}
   for qid,_ in pairs(DailyNotes.DB_Quests) do
      DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid]=1
   end
   DailyNotes.UpdateAQButtons()
   DailyNotes:UpdateListView()
end

function DN_AutoQuestSelectKill()
   local m = not DailyNotes.AQ_AllKillMarked
   if not m then m=nil end

   if not DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept then  DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept={} end
   for qid,qdata in pairs(DailyNotes.DB_Quests) do
      if (math.abs(qdata.typ)%16)==2 then
        DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid]= m
      end
   end
   DailyNotes.UpdateAQButtons()
   DailyNotes:UpdateListView()
end

function DN_AutoQuestSelectGather()
   local m = not DailyNotes.AQ_AllGatherMarked
   if not m then m=nil end

   if not DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept then  DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept={} end
   for qid,qdata in pairs(DailyNotes.DB_Quests) do
      if (math.abs(qdata.typ)%16)==4 then
        DN_Options[DailyNotes.DN_GetCurrentChar()].aq_accept[qid]= m
      end
   end
   DailyNotes.UpdateAQButtons()
   DailyNotes:UpdateListView()
end


------------
-- Daily counter
function DailyNotes.QUEST_MSG_DAILYRESET()
  DailyNotesDoAble:SetText("10/10")
end

function DN_List_UpdateDoAble()
  DailyNotesDoAble:SetText(DN_GetDailiesCount().."/10")
end


-----------------------------------------------------------------------
-- Configuration Dialog
-----------------------------------------------------------------------
function DailyNotes:DN_Show_Options()
  self:DN_Config_Load()
  ToggleUIFrame(DailyNotesConfigFrame)
end

function DailyNotes:DN_Config_Load()
  DailyNotesCharLevel:SetChecked(DN_Options.showcharlevel)
  DailyNotesTaker:SetChecked(DN_Options.takefilter)
  DailyNotesVerbose:SetChecked(DN_Options.verbose)
  DailyNotesCounterDisplay:SetChecked(not DN_Options.noitemcount)
  DailyNotesCounterDQ:SetChecked(DN_Options.dqionly)
  DailyNotesDebug:SetChecked(DN_Options.debug)

  if DN_Options.noitemcount then
    DailyNotesCounterDQ:Disable()
  else
    DailyNotesCounterDQ:Enable()
  end

--[===[@debug@
  DailyNotesDebug:Show()
--@end-debug@]===]
end

function DailyNotes:DN_Config_Save()
  DN_Options.showcharlevel = DailyNotesCharLevel:IsChecked()
  DN_Options.takefilter = DailyNotesTaker:IsChecked()
  DN_Options.verbose = DailyNotesVerbose:IsChecked()
  DN_Options.noitemcount = not DailyNotesCounterDisplay:IsChecked()
  DN_Options.dqionly = DailyNotesCounterDQ:IsChecked()
  DN_Options.debug = DailyNotesDebug:IsChecked()

  if DN_Options.noitemcount then
    DailyNotesCounterDQ:Disable()
  else
    DailyNotesCounterDQ:Enable()
  end

  if DailyNotesFrame:IsVisible() then
    DailyNotes:UpdateListView()
  end
end


-----------------------------------------------------------------------
-- interactions
-----------------------------------------------------------------------
function DailyNotes.OnLoad(this)
  this:RegisterEvent("VARIABLES_LOADED")
  this:RegisterEvent("CHAT_MSG_SYSTEM")
  this:RegisterEvent("CHAT_MSG_SYSTEM_GET")
  this:RegisterEvent("BAG_ITEM_UPDATE")
  this:RegisterEvent("QUEST_MSG_DAILYRESET")     -- never tested if this event is really fired
  this:RegisterEvent("QUEST_MSG_DAILY_OVERDONE") -- never tested if this event is really fired
  this:RegisterEvent("LOADING_END")
 -- this:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
  -- Note: QUEST_MSG_DAILY_COMPLETE is never called
end


function DailyNotes.OnEvent(event)
  if DailyNotes[event] then DailyNotes[event](arg1) end
end

function DailyNotes.QUEST_MSG_DAILY_OVERDONE()
  DEFAULT_CHAT_FRAME:AddMessage("DN: QUEST_MSG_DAILY_OVERDONE arg1="..tostring(arg1).." , arg2="..tostring(arg2))
end



function DailyNotes.VARIABLES_LOADED()

  SaveVariables("DN_Options")

  if AddonManager then
      -- set correct handles
      DN_addon.configFrame = DailyNotesFrame
      DN_addon.miniButton = DailyNotesMiniButton
      DN_addon.disableScript = function() DN_Options["disabled"] = true end
      DN_addon.enableScript  = function() DN_Options["disabled"] = nil end
      AddonManager.RegisterAddonTable(DN_addon)
  end

  ----------------------
  -- do version conversations
  local version=0
  local n=1000000
  (DN_Options.version or "0"):gsub("%d+", function(c) if n>0 then version=version+(tonumber(c))*n; n=n/100 end end)


  -- pre 1.7.0  
  if version<1070000 then
    -- delete old quest
    for name,data in pairs(DN_Options) do
      if type(data)=="table" then
        if string.find(name,".*%s+(%w*):(%w*)$") then
          DN_Options[name]=nil
        end
      end
    end

    -- convert names to ID
    for n,data in pairs(DN_Options) do
      if type(data)=="table" and data.aq_accept then

        data.FilterZoneName=nil
        local new_data={}
        for name,val in pairs(data.aq_accept) do
          local qid = DailyNotes:FindQuestByName(name)
          if val and qid then
            new_data[qid]=1
          end
        end
        data.aq_accept=new_data
      end
    end
  end
  DN_Options.version = DN_addon.version


end



function DailyNotes.LOADING_END()
  if not DN_Options[DailyNotes.DN_GetCurrentChar()] then DN_Options[DailyNotes.DN_GetCurrentChar()]={} end

  -- gather item names
  if not DailyNotes.DB_Item then
    local old_dis  = DN_Options["disabled"] -- disable self processing
    DN_Options["disabled"] = true
    DailyNotes.DB_Item={}
    for _,quest in pairs(DailyNotes.DB_Quests) do
      for itemid,_ in pairs(quest.items or {}) do
        if not DailyNotes.DB_Item[itemid] then
            GameTooltip:SetHyperLink( DailyNotes.CreateItemLink(itemid,1) )
            local itemname = _G[GameTooltip:GetName() .. "TextLeft1"]:GetText()
            if itemname then
              DailyNotes.DB_Item[itemid] = itemname
            end
        end
      end
    end
    GameTooltip:Hide()
    DN_Options["disabled"] = old_dis
  end

  --[===[@debug@
    if DailyNotes.TestDB then
      DailyNotes:TestDB()
      DailyNotes.TestDB=nil
    end
  --@end-debug@]===]
end


function DailyNotes.BAG_ITEM_UPDATE()
  if DailyNotesFrame:IsVisible() then
    DailyNotes:UpdateList()
  end
end


local function DN_sw_out(name,value)
  o = "disabled"
  if value then o="enabled" end
  DEFAULT_CHAT_FRAME:AddMessage(DN_addon.name .. " "..name..": ".. o)
end



SLASH_DailyNotes1 = "/dailynotes";
SLASH_DailyNotes2 = "/dn";
SlashCmdList["DailyNotes"] = function (editBox, msg)

  -- No command means show the UI
  if ( not msg or msg == "" ) then
    ToggleUIFrame(DailyNotesFrame)
    return;
  end



  local cmds={}
  for cm in string.gmatch(string.lower(msg), "%a+") do table.insert(cmds,cm) end

  local help = nil
  for i = 1,table.getn(cmds) do
    fl = string.sub(cmds[i],1,1)
    if fl == 'd' then
      DN_Options.debug = not DN_Options.debug
      DN_sw_out("DEBUG",DN_Options.debug)
    elseif fl == 'a' then
      DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest = not DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest
      DN_sw_out("Auto-Quest-Taker",DN_Options[DailyNotes.DN_GetCurrentChar()].autoquest)
    elseif fl == 'v' then
      DN_Options.verbose = not DN_Options.verbose
      DN_sw_out("VERBOSE",DN_Options.verbose)
    else
      DEFAULT_CHAT_FRAME:AddMessage("|cffff0000Unknown switch "..cmds[i])
      help = true
     end
  end

  if help then
    DEFAULT_CHAT_FRAME:AddMessage("|cffa0a0ff"..DN_addon.name .. " |cffe0e0e0"..DN_addon.version)
    DEFAULT_CHAT_FRAME:AddMessage("switches are:")
    DEFAULT_CHAT_FRAME:AddMessage(" d for debug")
    DEFAULT_CHAT_FRAME:AddMessage(" a for auto-quest-taker")
    DEFAULT_CHAT_FRAME:AddMessage(" v for more information")
  end

end




--[===[@debug@

--- DEBUG HELPER
ori_NpcTrackFrame_TrackPreview = NpcTrackFrame_TrackPreview
function NpcTrackFrame_TrackPreview( info )
  ori_NpcTrackFrame_TrackPreview(info)

  if( info and DN_Options.debug) then
    local msg = string.format( "%s=%i ( %.1f , %.1f )", info.name, info.npcID, info.x * 100, info.z * 100 );
    NpcTrackWorldMapFrameMsgBar_String:SetText( msg );
    NpcTrackWorldMapFrameMsgBar:Show();
  end
end
--@end-debug@]===]


